﻿using AntdUI;
using ClosedXML.Excel;
using Serilog;
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection;
using WorkTool2.Classes.Data;
using WorkTool2.Classes.Settings;
using WorkTool2.Helpers;
using WorkTool2.Interfaces;

namespace WorkTool2.Controls
{
    public partial class CherryPick : UserControl, IReload
    {
        private Form form;

        public CherryPick(Form _form)
        {
            form = _form;
            InitializeComponent();
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            ITask.Run(() =>
            {
                Reload();
            });
            project_select.Focus();
        }

        public void Reload()
        {
            tree.Items.Clear();
            project_select.Items.Clear();
            project_select.SelectedValue = -1;
            project_select.Items.Add(new SelectItem("全部", "全部"));
            foreach (var cherryPickSetting in SettingsHelper._cherryPickSettings)
            {
                var id = Guid.NewGuid().ToString();
                var it = new TreeItem(cherryPickSetting.ProjectName).SetName(cherryPickSetting.ProjectName).SetIcon("PlusCircleFilled").SetSubTitle("新增").SetID(id).SetTag(cherryPickSetting);
                foreach (var branch in cherryPickSetting.Branches)
                {
                    it.SetSub(new TreeItem(branch).SetIcon("DeleteFilled").SetSubTitle("删除"));
                }
                tree.Items.Add(it);
                project_select.Items.Add(new SelectItem(cherryPickSetting.ProjectName, id));
            }
            tree.ExpandAll();
        }

        private void addBranch_btn_Click(object sender, EventArgs e)
        {
            Spin.open(form, "正在处理中，请耐心等候...",
                config =>
                {
                    try
                    {
                        if (!addBranch_input.ReadOnly)
                        {
                            var project = tree.SelectItem;
                            if (project == null)
                            {
                                Modal.open(form, "错误", "请点击要添加分支的项目", TType.Error);
                                return;
                            }
                            var branch = addBranch_input.Text.Trim();
                            if (string.IsNullOrEmpty(branch))
                            {
                                Modal.open(form, "错误", "分支名不能为空", TType.Error);
                                return;
                            }
                            if (project.Sub.Exists(x => x.Text.Equals(branch)))
                            {
                                Modal.open(form, "错误", "已存在相同的分支名", TType.Error);
                                return;
                            }
                            project.SetSub(new TreeItem(branch).SetIcon("DeleteFilled").SetSubTitle("点击删除"));
                            addBranch_input.Text = "";
                            Notification.success(form, "添加分支成功", $"已在【{project.Text}】上添加分支【{branch}】", AntdUI.TAlignFrom.Top);
                        }
                    }
                    catch (Exception ex)
                    {
                        Modal.open(form, "错误", $"添加分支失败: {ex.Message}", TType.Error);
                        Log.Error(ex, ex.Message);
                    }
                },
                () => { }
            );
        }

        private void button_Click(object sender, EventArgs e)
        {
            Spin.open(form, "正在处理中，请耐心等候...",
                config =>
                {
                    try
                    {
                        var projectName = project_select.SelectedValue?.ToString();
                        if (string.IsNullOrEmpty(projectName))
                        {
                            Modal.open(form, "错误", "请选择要查询的项目", TType.Error);
                            return;
                        }
                        var selectItems = project_select.Items.ToList().Where(x => x != null).Select(x => (SelectItem)x).Where(x => x.Tag.ToString() != "全部").ToList();
                        if (project_select.SelectedIndex != 0)
                        {
                            selectItems = selectItems.Where(x => x.Tag.ToString().Equals(projectName)).ToList();
                        }
                        var pathList = new List<string>();
                        foreach (var selectItem in selectItems)
                        {
                            var cherryPickTree = tree.Items.FirstOrDefault(x => x.ID.Equals(selectItem.Tag.ToString()));
                            var cherryPickSettings = (CherryPickSettings)cherryPickTree.Tag;
                            config.Text = $"正在获取项目【{cherryPickSettings.ProjectName}】的Git信息...";
                            var branches = new Dictionary<string, List<GitCommitRecord>> { };
                            var (IsSuccess, Message) = GitHelper.ExecuteGitCommand("fetch", cherryPickSettings.ProjectPath);
                            if (!string.IsNullOrWhiteSpace(Message))
                                Log.Error($"[git fetch]{Message}");
                            using var workbook = new XLWorkbook();
                            var sheetIndex = 1;
                            foreach (var branch in cherryPickTree.Sub.Select(x => x.Text).Distinct())
                            {
                                config.Text = $"正在获取项目【{cherryPickSettings.ProjectName}】分支【{branch}】的提交信息...";
                                var (Data, ErrorMessage) = GitHelper.GetGitCommit(branch, cherryPickSettings.Author, cherryPickSettings.ProjectPath);
                                if (!string.IsNullOrWhiteSpace(ErrorMessage))
                                {
                                    config.Text = $"获取项目【{cherryPickSettings.ProjectName}】分支【{branch}】的提交信息失败\n\t错误信息：\n\t{ErrorMessage}";
                                    continue;
                                }
                                var branchList = Data;
                                config.Text = $"正在处理项目【{cherryPickSettings.ProjectName}】分支【{branch}】的数据...";
                                var worksheetName = branch.Replace("/", "_");
                                worksheetName = worksheetName.Length > 31 ? worksheetName[..31] : worksheetName;
                                var worksheet = workbook.Worksheets.Add(worksheetName, sheetIndex);
                                var columnIndex = 0;
                                var properties = typeof(GitCommitRecord).GetProperties();
                                for (int i = 0; i < properties.Length; i++)
                                {
                                    var prop = properties[i];
                                    var descriptionAttr = prop.GetCustomAttribute<DescriptionAttribute>();
                                    if (descriptionAttr != null)
                                    {
                                        worksheet.Cell(1, i + 1).Value = descriptionAttr.Description;
                                        worksheet.Cell(1, i + 1).Style.Font.Bold = true;
                                        worksheet.Cell(1, i + 1).Style.Font.FontColor = XLColor.White;
                                        worksheet.Cell(1, i + 1).Style.Fill.BackgroundColor = XLColor.FromArgb(0, 112, 192);
                                        columnIndex++;
                                    }
                                }
                                worksheet.Cell(2, 1).InsertData(branchList);
                                worksheet.Columns().AdjustToContents();
                                var range = worksheet.Range(1, 1, branchList.Count + 1, columnIndex);
                                range.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
                                range.Style.Border.InsideBorder = XLBorderStyleValues.Thin;
                                sheetIndex++;
                                branches.Add(branch, branchList);
                            }
                            config.Text = $"生成项目【{cherryPickSettings.ProjectName}】Excel文件中...";
                            if (sheetIndex > 1)
                            {
                                cherryPickSettings.Branches = [.. branches.Keys];
                                var allWorksheetName = string.IsNullOrEmpty(cherryPickSettings.ProjectName) ? "cherry-pick" : cherryPickSettings.ProjectName.Replace("/", "_") + "_cherry-pick";
                                allWorksheetName = allWorksheetName.Length > 31 ? allWorksheetName[..31] : allWorksheetName;
                                var allWorksheet = workbook.Worksheets.Add("cherry-pick", 0);
                                allWorksheet.Cell(1, 1).Value = "git cherry-pick";
                                allWorksheet.Cell(1, 2).Value = "简短提交id";
                                allWorksheet.Cell(1, 3).Value = "完整提交id";
                                allWorksheet.Cell(1, 4).Value = "提交信息";
                                var index = 5;
                                foreach (var branch in cherryPickSettings.Branches)
                                {
                                    allWorksheet.Cell(1, index).Value = branch;
                                    index++;
                                }
                                for (int i = 1; i < index; i++)
                                {
                                    allWorksheet.Cell(1, i).Style.Font.Bold = true;
                                    allWorksheet.Cell(1, i).Style.Font.FontColor = XLColor.White;
                                    allWorksheet.Cell(1, i).Style.Fill.BackgroundColor = XLColor.FromArgb(0, 112, 192);
                                }
                                var rowIndex = 2;
                                foreach (var item in branches[cherryPickSettings.Branches[0]])
                                {
                                    var shortCommitIdCell = allWorksheet.Cell(rowIndex, 2);
                                    shortCommitIdCell.Value = item.ShortCommitId;
                                    var commitIdCell = allWorksheet.Cell(rowIndex, 3);
                                    commitIdCell.Value = item.CommitId;
                                    var messageCell = allWorksheet.Cell(rowIndex, 4);
                                    messageCell.Value = item.Message;
                                    var masterCell = allWorksheet.Cell(rowIndex, 5);
                                    masterCell.Value = "Y";
                                    masterCell.Style.Font.FontColor = XLColor.White;
                                    masterCell.Style.Fill.BackgroundColor = XLColor.Green;
                                    var columnIndex = 6;
                                    var isGit = true;
                                    foreach (var prop in branches.Keys.Where(x => !x.Equals(cherryPickSettings.Branches[0])))
                                    {
                                        var isBool = branches[prop].Exists(x => x.CommitId.Equals(item.CommitId));
                                        if (!isBool)
                                        {
                                            if (branches[prop].Exists(x => x.Message.Equals(item.Message)))
                                            {
                                                isBool = true;
                                            }
                                            else
                                            {
                                                isBool = branches[prop].Any(x => x.Message.Contains(item.ShortCommitId));
                                            }
                                        }
                                        var cell = allWorksheet.Cell(rowIndex, columnIndex);
                                        if (isBool)
                                        {
                                            cell.Value = "Y";
                                            cell.Style.Font.FontColor = XLColor.White;
                                            cell.Style.Fill.BackgroundColor = XLColor.Green;
                                        }
                                        else
                                        {
                                            isGit = false;
                                            cell.Value = "N";
                                            cell.Style.Fill.BackgroundColor = XLColor.FromArgb(255, 255, 0);
                                        }
                                        columnIndex++;
                                    }
                                    if (!isGit)
                                    {
                                        var gitCell = allWorksheet.Cell(rowIndex, 1);
                                        gitCell.Value = isGit ? "" : $"git cherry-pick {item.ShortCommitId}";
                                        allWorksheet.Row(rowIndex).Cells(1, 4).Style.Fill.SetBackgroundColor(XLColor.FromArgb(255, 255, 0));
                                    }
                                    rowIndex++;
                                }
                                allWorksheet.Columns().AdjustToContents();
                                var allRange = allWorksheet.Range(1, 1, rowIndex - 1, index - 1);
                                allRange.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
                                allRange.Style.Border.InsideBorder = XLBorderStyleValues.Thin;
                            }
                            var excelPath = Path.Combine(SettingsHelper._fileSettings.SaveFolder, $"{cherryPickSettings.ProjectName}_GitCommitRecord_{DateTime.Now:yyyyMMdd}{(SettingsHelper._fileSettings.SaveFileNameRandom ? $"_{new Random().Next(10000, 99999)}" : "")}.xlsx");
                            workbook.SaveAs(excelPath);
                            config.Text = $"项目【{cherryPickSettings.ProjectName}】Excel文件生成成功...";
                            pathList.Add(excelPath);
                        }
                        if (new Modal.Config(form, "成功", "是否打开文件？", TType.Success)
                        {
                            OnButtonStyle = (id, btn) =>
                            {
                                btn.BackExtend = "135, #6253E1, #04BEFE";
                            },
                            CancelText = "否",
                            OkText = "是"
                        }.open() == DialogResult.OK)
                        {
                            foreach (var path in pathList)
                            {
                                Process.Start(new ProcessStartInfo
                                {
                                    FileName = path,
                                    UseShellExecute = true
                                });
                            }
                        }
                        (form as Main).AddHistoryData(pathList.Select(x => new HistoryData("Git分支比较", x)).ToList()).ConfigureAwait(false);
                    }
                    catch (Exception ex)
                    {
                        Modal.open(form, "错误", $"生成报表失败: {ex.Message}", TType.Error);
                        Log.Error(ex, ex.Message);
                    }
                },
                () => { }
            );
        }

        private void tree_NodeMouseClick(object sender, TreeSelectEventArgs e)
        {
            Spin.open(form, "正在处理中，请耐心等候...",
                 config =>
                   {
                       try
                       {
                           addBranch_input.InvokeIfRequired(() =>
                           {
                               addBranch_input.ReadOnly = e.Item.Name == null;
                           });
                           addBranch_btn.InvokeIfRequired(() =>
                           {
                               addBranch_btn.Enabled = e.Item.Name != null;
                           });
                           if (e.Item.Name == null)
                           {
                               e.Item.PARENTITEM.Sub.Remove(e.Item);
                               Notification.success(form, "删除分支成功", $"已在【{e.Item.PARENTITEM.Text}】上删除分支【{e.Item.Text}】", AntdUI.TAlignFrom.Top);
                           }
                           if (!addBranch_input.ReadOnly)
                           {
                               addBranch_input.InvokeIfRequired(() =>
                               {
                                   addBranch_input.Focus();
                               });
                           }
                           else
                           {
                               panel1.InvokeIfRequired(() =>
                               {
                                   panel1.Focus();
                               });
                           }
                       }
                       catch (Exception ex)
                       {
                           Modal.open(form, "错误", $"删除分支失败: {ex.Message}", TType.Error);
                           Log.Error(ex, ex.Message);
                       }
                   },
                   () => { }
               );
        }

        private void label1_Click(object sender, EventArgs e)
        {
            Reload();
        }
    }
}